﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Microsoft.Practices.Unity;
using SpectrumAnalyser.Common.Hosting;
using SpectrumAnalyser.Common.Logs;
using SpectrumAnalyser.Config.Client;
using SpectrumAnalyser.CustomControls.Wpf.BusyIndicator;
using SpectrumAnalyser.Data.Files.SpectrumDatabaseContracts.Repository;
using SpectrumAnalyser.Data.Files.SpectrumFileReaderContracts;
using SpectrumAnalyser.ModelObjects;
using SpectrumAnalyser.ModelObjects.Enum;
using SpectrumAnalyser.ServiceClientProxy;
using SpectrumAnalyser.Services.ExpertiseResultStorageServiceContracts;
using SpectrumAnalyser.Shell.Helpers;
using System.Net;
using System;

namespace SpectrumAnalyser.Shell
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private static IUnityContainer _container;

        private static void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            e.Handled = true;
            Logger.Log(e.Exception.ToString());
        }

        private void RegisterServices()
        {
            _container.Resolve<ClientBootstrapperBase>(new ParameterOverride("instanceName", "MyInstance"))
                      .RegisterServices(new List<Type>
                          {
                              typeof (IExpertiseStorageServiceContract)
                          });

            try
            {
                _container.Resolve<IExpertiseStorageServiceContract>().Ping();
            }
            catch (Exception ex)
            {
                Logger.Log(ex.ToString());
            }

            //TODO: use host from config.
            var hostUri = WcfHelper.GetEndpointUri(UriScheme.Http, "IConfigService");
            _container.Resolve<ConfigClient>().Initialize(hostUri.ToString());
        }

        private void RegisterFilebasedRepositories()
        {
            var currentLocation = Directory.GetCurrentDirectory();
            var repositoryFiles = Directory.GetFiles(currentLocation, "SpectrumAnalyser.Data.Files.*.dll");
            foreach (var repositoryFile in repositoryFiles)
            {
                Assembly assembly = Assembly.LoadFile(repositoryFile);
                var allTypes = assembly.GetTypes().ToList();
                foreach (var allType in allTypes)
                {
                    var fileReaderTypes = allType.GetInterfaces().Where(x => x.GetTypeInfo().AsType() == typeof(ISpectrumFileReader));
                    if (fileReaderTypes.Any())
                    {
                        var spectrumDataBaseInstance = (ISpectrumFileReader)Activator.CreateInstance(allType);
                        UnityContainer.RegisterInstance(typeof (ISpectrumFileReader),
                                                        spectrumDataBaseInstance.SpectrumFileReaderType,
                                                        spectrumDataBaseInstance);
                    }
                    var spectrumDataBaseTypes = allType.GetInterfaces().Where(x => x.GetTypeInfo().AsType() == typeof(ISpectrumLinesRepository));
                    if (spectrumDataBaseTypes.Any())
                    {
                        var spectrumDataBaseInstance = (ISpectrumLinesRepository) Activator.CreateInstance(allType);
                        UnityContainer.RegisterInstance(typeof (ISpectrumLinesRepository),
                                                        spectrumDataBaseInstance.ConnectionType,
                                                        spectrumDataBaseInstance);
                    }
                }
            }
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            _container = new UnityContainer();
            _container.RegisterType<IAppConfigHelper, AppConfigHelper>(new ContainerControlledLifetimeManager());

            RegisterFilebasedRepositories();
            RegisterServices();

            //inject unity container in MainWindow
            _container.Resolve<MainWindow>().Show();

            Current.DispatcherUnhandledException += AppDispatcherUnhandledException;
        }

        public static IUnityContainer UnityContainer
        {
            get { return _container; }
        }

        public static IAppConfigHelper AppConfigHelper
        {
            get
            {
                return _container.Resolve<IAppConfigHelper>();
            }
        }

        public static ISpectrumFileReader SpectrumFileReader
        {
            get { return _container.Resolve<ISpectrumFileReader>(); }
        }

        public static ISpectrumLinesRepository SpectrumPeaksRepository
        {
            get { return _container.Resolve<ISpectrumLinesRepository>(); }
        }

        public static BusyIndicator BusyIndicator;
    }
}
